package com.podium.web.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.podium.auth.utils.SecurityUtils;
import com.podium.comment.utils.StringUtils;
import com.podium.web.system.entity.*;
import com.podium.web.system.mapper.SysUserMapper;
import com.podium.web.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 邵文泽
 * @description 系统用户
 * @date Mon Apr 28 16:21:15 CST 2025
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysRoleService roleService;

    @Autowired
    private SysMenuService menuService;

    @Autowired
    private SysUserRoleService userRoleService;

    @Autowired
    private SysRoleMenuService roleMenuService;

    @Override
    public IPage<SysUser> page(Page<SysUser> page, SysUser sysUser) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SysUser::getDelFlag, 0)
                .like(StringUtils.hasLength(sysUser.getUsername()), SysUser::getUsername, sysUser.getUsername())
                .like(StringUtils.hasLength(sysUser.getNickName()), SysUser::getNickName, sysUser.getNickName())
                .like(StringUtils.hasLength(sysUser.getPhone()), SysUser::getPhone, sysUser.getPhone())
                .like(StringUtils.hasLength(sysUser.getEmail()), SysUser::getEmail, sysUser.getEmail())
                .like(StringUtils.hasLength(sysUser.getAddress()), SysUser::getAddress, sysUser.getAddress())
        ;
        return super.page(page, queryWrapper);
    }

    @Override
    public List<SysUser> list(SysUser sysUser) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SysUser::getDelFlag, 0)
                .like(StringUtils.hasLength(sysUser.getUsername()), SysUser::getUsername, sysUser.getUsername())
                .like(StringUtils.hasLength(sysUser.getNickName()), SysUser::getNickName, sysUser.getNickName())
                .like(StringUtils.hasLength(sysUser.getPhone()), SysUser::getPhone, sysUser.getPhone())
                .like(StringUtils.hasLength(sysUser.getEmail()), SysUser::getEmail, sysUser.getEmail())
                .like(StringUtils.hasLength(sysUser.getAddress()), SysUser::getAddress, sysUser.getAddress())
        ;
        return super.list(queryWrapper);
    }

    @Override
    public SysUser getById(Long id) {
        SysUser sysUser = super.getById(id);
        sysUser.setPassword(null);
        return sysUser;
    }

    @Override
    public boolean save(SysUser sysUser) {
        sysUser.setPassword(SecurityUtils.encryptPassword(sysUser.getPassword()));
        sysUser.setDelFlag(0L);
        sysUser.setCreateBy(SecurityUtils.getUsername());
        sysUser.setCreateTime(LocalDateTime.now());
        return super.save(sysUser);
    }

    @Override
    public boolean updateById(SysUser sysUser) {
        sysUser.setUpdateBy(SecurityUtils.getUsername());
        sysUser.setUpdateTime(LocalDateTime.now());
        return super.updateById(sysUser);
    }

    @Override
    public void removeById(Long id) {
        super.removeById(id);
    }

    @Override
    public SysUser findByUserName(String username) {
        SysUser sysUser = super.getOne(new QueryWrapper<SysUser>().lambda()
                .eq(SysUser::getUsername, username), false);

        return Optional.ofNullable(sysUser)
                .filter(u -> u.getId() != null)
                .map(this::enrichUserInfo)
                .orElse(null);
    }

    private SysUser enrichUserInfo(SysUser sysUser) {
        Long userId = sysUser.getId();

        if(userId == 1){
            sysUser.setPermissions(Set.of("**:**:**"));
            return sysUser;
        }

        // 获取用户关联的角色
        SysUserRole userRoleQuery = new SysUserRole();
        userRoleQuery.setUserId(userId);
        List<SysUserRole> userRoles = userRoleService.list(userRoleQuery);

        List<Long> roleIds = userRoles.stream()
                .map(SysUserRole::getRoleId)
                .toList();

        if (roleIds.isEmpty()) {
            log.debug("用户 {} 没有关联任何角色", sysUser.getUsername());
            return sysUser;
        }

        // 查询角色列表
        List<SysRole> roles = roleService.listByIds(roleIds);
        sysUser.setRoles(roles.stream().map(SysRole::getRoleKey).collect(Collectors.toSet()));

        // 否则获取角色对应的菜单ID，并设置权限
        List<SysRoleMenu> roleMenus = roleMenuService.listByRoleId(roleIds);

        Set<Long> menuIds = roleMenus.stream()
                .map(SysRoleMenu::getMenuId)
                .collect(Collectors.toSet());

        if (!menuIds.isEmpty()) {
            List<SysMenu> menus = menuService.listByIds(menuIds);
            Set<String> permsList = menus.stream()
                    .map((e) -> {
                        if (StringUtils.hasLength(e.getPerms())) {
                            return e.getPerms();
                        }
                        return null;
                    }).filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            sysUser.setPermissions(permsList);
        }
        return sysUser;
    }

}